<!-- 材料智能体-通用大模型 -->
<template>
  <!-- 顶部搜索区 -->
  <div class="main-app" v-loading="loading">
    <el-breadcrumb separator-class="el-icon-arrow-right" style="margin-top: 5px; margin-bottom: 15px;">
      <el-breadcrumb-item :to="{path:'/'}">{{$t('common.nav.home')}}</el-breadcrumb-item>
      <el-breadcrumb-item>{{$t('common.nav.materialIntelligentAgent')}}</el-breadcrumb-item>
      <el-breadcrumb-item>{{$t('common.nav.universalBigModel')}}</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- Tab栏 -->
    <el-tabs v-model="activeName">
      <el-tab-pane :label="$t('common.label.dialogue')" name="dialogue">
        <!-- 对话区域 -->
        <el-row :gutter="10">
          <!-- <el-col :span="4">
            <el-card shadow="hover" class="box-card">
              <el-button type="primary" icon="el-icon-plus" @click="createDialogue">新建对话</el-button>
              <el-divider content-position="left">历史对话</el-divider>
            </el-card>
          </el-col> -->
          <!-- 聊天框区域 -->
          <el-col :span="24">
            <div class="dialog-text-box" ref="scrollContainer">
              <!-- <div v-for="(item,index) in dialogueList" :key="index" class="text-item" :class="item.position === 'right' ? 'text-item-right' : ''"> -->
              <div v-for="(item,index) in dialogueList" :key="index" class="text-item">
                <template v-if="item.position === 'left'">
                  <div class="chat-system-head"></div>
                  <el-row class="chat-msg-info">
                    <el-col>
                      <div class="info">
                        <span>{{item.name}}</span>&nbsp;<span>{{item.time}}</span>
                      </div>
                    </el-col>
                    <el-col style="margin-top: 10px;">
                      <div class="chat-box">{{item.content}}</div>
                    </el-col>
                  </el-row>
                </template>
                <template v-else>
                  <div class="chat-user-head"></div>
                  <el-row class="chat-msg-info">
                    <el-col>
                      <div class="info">
                        <span>{{item.name}}</span>&nbsp;<span>{{item.time}}</span>
                      </div>
                    </el-col>
                    <el-col style="margin-top: 10px;">
                      <div class="chat-box">{{item.content}}</div>
                    </el-col>
                  </el-row>
                  <!-- <div class="chat-box-right">{{item.content}}</div>
                  <div class="chat-user-head"></div> -->
                </template>
              </div>
            </div>
            <div class="chat-input">
              <el-form ref="form" :model="form" :rules="rules" label-width="0%">
                <el-form-item label="" prop="content">
                  <el-row :gutter="5">
                    <el-col :span="3">
                      <el-select v-model="form.chatMode" prop="chatMode" :placeholder="$t('common.placeholder.pleaseSelect')">
                        <el-option :label="$t('common.label.domainKnowledgeQA')" value="0" />
                        <el-option :label="$t('common.label.autonomousLearning')" value="1" />
                      </el-select>
                    </el-col>
                  </el-row>
                  <el-row :gutter="10" style="margin-top: 1%;">
                    <el-col :span="2">
                      <el-button type="primary" icon="el-icon-plus" @click="createDialogue">{{$t('common.button.addDialogue')}}</el-button>
                    </el-col>
                    <el-col :span="20">
                      <el-input v-model="form.content" :placeholder="$t('common.placeholder.pleaseInput')" style="width: 105%;margin-left: -1%;">
                      	<template #suffix>
                      		<!-- <img v-if="!isRecording" src="../../../assets/icon/voice.png" class="btn-voice" @touchstart="voiceInput">
                          <img v-else src="../../../assets/icon/voice_lock.png" class="btn-voice" @touchend="voiceInput"> -->
                          <el-tooltip effect="dark" :content="$t('common.prompt.info.recordingTip')" placement="top">
                            <img :src="!isRecording ? require('../../../assets/icon/voice.png') : require('../../../assets/icon/voice_lock.png')" class="btn-voice" @mousedown="voiceInput" @mouseup="voiceInput">
                          </el-tooltip>
                      	</template>
                      </el-input>
                    </el-col>
                    <el-col :span="1">
                      <el-button type="primary" style="margin-left: 98%;" :loading="isLoading" @click="sending">{{$t('common.button.sending')}}</el-button>
                    </el-col>
                  </el-row>
                </el-form-item>
              </el-form>
            </div>
          </el-col>
        </el-row>
        <!-- <audio v-if="recordedAudio" ref="audioPlayer" controls></audio> -->
      </el-tab-pane>
      <el-tab-pane :label="$t('common.label.intelligentTools')" name="second">
        <el-button type="primary" style="width: 200px" @click="">{{$t('common.label.multiscaleComputing')}}</el-button>
        <el-button type="primary" style="width: 200px" @click="">{{$t('common.label.automationExperiment')}}</el-button>
        <el-button type="primary" style="width: 200px" @click="">{{$t('common.label.bigModelMaterialsScience')}}</el-button>
        <el-button type="primary" style="width: 200px" @click="">{{$t('common.label.machineLearning')}}</el-button>
        <el-button type="primary" style="width: 200px" @click="">{{$t('common.label.externalTools')}}</el-button>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
  import {
    BaiduAccessToken,
    BaiduSpeechToText,
    BaiduSpeechToTextApi,
    StartDialogue,                      // 获取一个序列任务id
    ConverSations,                      // 对话任务
    Self_Learning,                      // 自学习
    DialogueStatus                      // 当前对话任务状态查询
  } from "../../../api/bigModel.js";
  import {
    getThisTimeStr,
  } from "../../../utils/index.js";
  export default {
    // 页面公共变量
    data() {
      return {
        // 基本配置
        activeName: "dialogue",         // 当前选中的Tab页面
        loading: false,                 // 加载状态

        // 对话任务配置
        thisSequentialTaskId: "",       // 当前正在进行的对话任务ID

        // 聊天框配置
        dialogueList: [],               // 当前对话记录数据
        answerText: "",                 // AI回答的文本
        typingSpeed: 30,                // 打字速度（每毫秒输出一个字符）
        waitTimer: null,                // 等待响应计时器

        // 语音输入配置
        audioContext: null,             // 音频内容组件
        mediaRecorder: null,            // 录音组件
        recordedAudio: null,            // 录音播放器组件
        isRecording: false,             // 是否正在录音
        chunks: [],                     // 已录音内容

        // 提交表单内容
        form: {
          chatMode: "0",                // 聊天模式 0:领域知识问答 1:自主学习
          content: ""                   // 用户输入的内容
        }
      };
    },
    // 页面创建完成事件
    async created() {
      await this.init();
    },
    beforeDestroy() {
      clearInterval(this.waitTimer);
    },
    // 页面相关方法
    methods: {
      // 初始化加载事件
      async init() {
        // 启动加载框
        this.loading = true;

        // 新建对话
        this.createDialogue();
        //this.thisSequentialTaskId = '0017394b-fdd1-4804-9051-f7e4a07eedb4';

        // 初始化语音功能
        this.initRecording();

        // 关闭加载框
        this.loading = false;
      },
      // 新建对话
      async createDialogue() {
        // 清空页面显示的对话内容
        this.dialogueList = [];

        // 创建新对话任务
        await StartDialogue().then(res => {
          // 设置新对话任务ID
          this.thisSequentialTaskId = res.sequential_task_id;

          // 返回结果
          this.$message({ type: 'success', message: res.message });
        });
      },
      // 语音输入事件
      voiceInput() {
        if (this.isRecording === false) {
          this.startRecording();
        } else {
          this.stopRecording();
        }
      },
      // 发送消息事件
      async sending() {
        // 如果输入内容为空时则弹出提示
        if(this.form.content === "") {
          this.$message({ type: 'error', message: this.$t('common.prompt.error.sendContentCannotBeEmpty') });
          return;
        }

        // 发送对话任务
        if (this.form.chatMode === "0") {
          // 领域知识问答
          await ConverSations({
            user_input: {
              query: this.form.content,
              sequential_task_id: this.thisSequentialTaskId
            }
          }).then(res => {
            // 等待任务返回结果
            this.waitTimer = setInterval(async () => {
              DialogueStatus(res.current_task_id).then((res) => {
                if (res.status === "done") {
                  clearInterval(this.waitTimer);
                  this.verbatimDisplayText(res.result.current_answer);
                }
              });
            }, 1500);
          });
        } else {
          // 自主学习
          await Self_Learning({
            learning_input: {
              query: this.form.content,
              sequential_task_id: this.thisSequentialTaskId
            }
          }).then(res => {
            // 等待任务返回结果
            this.waitTimer = setInterval(async () => {
              DialogueStatus(res.current_task_id).then((res) => {
                if (res.status === "done") {
                  clearInterval(this.waitTimer);
                  this.verbatimDisplayText(res.result);
                }
              });
            }, 1500);
          });
        }

        // 填充用户对话内容
        this.dialogueList.push({
          name: this.$t('common.label.user'),
          content: this.form.content,
          time: getThisTimeStr(),
          position: 'right'
        });

        // 填充AI回复内容
        let AiResult = {
          name: this.$t('common.label.intelligentRobot'),
          content: '',
          time: getThisTimeStr(),
          position: 'left'
        };
        this.dialogueList.push(AiResult);
        this.verbatimDisplayText(this.$t('common.prompt.info.thinking'));
      },
      // 逐字显示文本内容
      verbatimDisplayText(textData) {
        // 清空临时内容
        this.dialogueList[this.dialogueList.length-1].content = '';

        // 获取聊天内容容器
        const container = this.$refs.scrollContainer;

        let index = 0;
        const timer = setInterval(() => {
          if (index < textData.length) {
            this.dialogueList[this.dialogueList.length-1].content += textData[index];
            index++;
          } else {
            clearInterval(timer);
          }

          if (container) {
            container.scrollTop = container.scrollHeight; // 将滚动位置设置为最底部
          }
        }, this.typingSpeed);

        // 清空输入内容
        this.form.content = "";
      },
      // 初始化语音功能
      initRecording() {
        this.audioContext = new AudioContext();
        this.chunks = [];
      },
      // 开始录音事件
      startRecording() {
        try {
          this.audioContext = new AudioContext();
          // 初始化录音设备
          navigator.mediaDevices.getUserMedia({audio: true}).then(stream => {
            this.isRecording = true;
            this.mediaRecorder = new MediaRecorder(stream);
            this.mediaRecorder.addEventListener('dataavailable', this.handleDataAvailable);
            // 启动录音
            this.mediaRecorder.start();
            this.mediaRecorder.addEventListener("stop", () => {
              stream.getTracks().forEach((track) => track.stop());

              //let that = this;

              // // 获取已录音内容
              // const blob = new Blob(this.chunks, { type: 'application/octet-stream' });

              // // 将BLOB对象转换为PCM文件
              // let reader = new FileReader();
              // reader.readAsText(blob);
              // reader.onloadend = function() {
              //   let pcmData = reader.result;
              //   // console.log('PCM文件内容：', pcmData);

              //   let blobBase64Str = '';
              //   that.blobToBase64(blob).then(res => {
              //     blobBase64Str = res.toString();
              //     that.$message({ type: 'info', message: that.$t('common.prompt.info.processing') });
              //     that.loading = true;

              //     // 将语音内容转换为文本
              //     BaiduSpeechToText({
              //       SpeechFile: pcmData,
              //       Speech: blobBase64Str.split('base64,')[1],
              //       Length: blob.size
              //     }).then((res) => {
              //       that.loading = false;
              //       if (res.data.result_data === '') {
              //         that.$message({ type: 'info', message: that.$t('common.prompt.info.notHaveSpeech') });
              //       }
              //       that.form.content = res.data.result_data;
              //     });
              //   });
              // };

              // 获取已录音内容
              const blob = new Blob(this.chunks, { type: 'audio/pcm' });
              let blobBase64Str = '';
              this.blobToBase64(blob).then(res => {
                blobBase64Str = res.toString();
                this.$message({ type: 'info', message: this.$t('common.prompt.info.processing') });
                this.loading = true;

                // 将语音内容转换为文本
                BaiduSpeechToText({
                  Speech: blobBase64Str.split('base64,')[1],
                  Length: blob.size
                }).then((res) => {
                  this.loading = false;
                  if (res.data.result_data === '') {
                    this.$message({ type: 'info', message: this.$t('common.prompt.info.notHaveSpeech') });
                  }
                  this.form.content = res.data.result_data;
                });
              });

              // 清空录音内容缓存
              this.chunks = [];
            });
            this.$message({ type: 'success', message: this.$t('common.prompt.info.recording') });
          }).catch(error => {
            // 发生异常, 停止录音
            console.error(error)
            this.isRecording = false;
            this.$message({ type: 'error', message: this.$t('common.prompt.error.deviceNotConnected') });
          });
        } catch(ex) {
          console.error(ex)
          this.isRecording = false;
          //this.$message({ type: 'error', message: '当前为演示版本, 无法使用语音输入功能' });
        }
      },
      // 结束录音事件
      stopRecording() {
        // 停止录音
        this.isRecording = false;
        this.mediaRecorder.stop();

        // // 获取已录音内容
        // const blob = new Blob(this.chunks, { type: 'audio/pcm' });
        // // const formData = new FormData();
        // // formData.append('audio', blob, 'recording.webm');

        // if (blob.size <= 0) {
        //   this.$message({ type: 'error', message: this.$t('common.prompt.error.noSpeech') });
        //   return;
        // }

        // let blobBase64Str = '';
        // this.blobToBase64(blob).then(res => {
        //   blobBase64Str = res.toString();
        //   //console.log(blobBase64Str);

        //   this.$message({ type: 'info', message: this.$t('common.prompt.info.processing') });
        //   this.loading = true;

        //   // 将语音内容转换为文本
        //   BaiduSpeechToText({
        //     Speech: blobBase64Str.split('base64,')[1],
        //     //Speech: blobBase64Str,
        //     Length: blob.size
        //   }).then((res) => {
        //     this.loading = false;
        //     if (res.data.result_data === '') {
        //       this.$message({ type: 'info', message: this.$t('common.prompt.info.notHaveSpeech') });
        //     }
        //     this.form.content = res.data.result_data;
        //   });

        //   // 清空录音内容缓存
        //   //this.chunks = [];
        //   this.chunks = this.chunks.filter(function(item) { return item.size === 0; });
        // });
      },
      // 录音任务处理事件
      handleDataAvailable(event) {
        this.chunks.push(event.data);
        // this.chunks = event.data;
        // console.log(this.chunks);
        if (this.mediaRecorder.state === 'inactive') {
          this.processRecordedAudio();
        }
      },
      // 音频播放内容设置
      processRecordedAudio() {
        const blob = new Blob(this.chunks, {type: 'audio/webm'});
        // this.recordedAudio = URL.createObjectURL(blob);
        //this.$refs.audioPlayer.src = this.recordedAudio;
      },
      // Blob转Base64字符串
      blobToBase64(blob) {
        return new Promise((resolve, reject) => {
          const fileReader = new FileReader();
          fileReader.onload = (e) => {
            resolve(e.target.result);
          };
          // readAsDataURL
          fileReader.readAsDataURL(blob);
          fileReader.onerror = () => {
            reject(new Error('文件流异常'));
          };
        });
      },
    },
  };
</script>

<style lang="scss" scoped>
/*对话框框架*/
::v-deep .el-card__body {
  padding: 15px;
}
.flex-row {
  display: flex;
  flex-direction: row;
}
.justify-between {
  display: flex;
  justify-content: space-between;
}

.dialog-text-box {
  height: 68vh;
  padding: 1%;
  background-color: #F8F8F8;
  overflow-y: auto;
}
// .dialog-text-box::-webkit-scrollbar {
//   display: none;
// }
.text-item {
  display: flex;
  //align-items: center;
  margin-bottom: 1%;
  &:last-child { margin-bottom: 0; }
}
.chat-box {
  font-size: 18px;
  margin-left: 5px;
  padding: 8px;
  background: #FFFFFF;
  position: relative;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  max-width: 1000px;
  word-wrap: break-word;
  white-space: pre-line;
}
.chat-box:before {
  content: "";
  position: absolute;
  right: 100%;
  top: 50%;
  width: 0;
  height: 0;
  border-top: 9px solid transparent;
  border-right: 8px solid #FFFFFF;
  border-bottom: 9px solid transparent;
  transform: translateY(-50%);
}
.chat-box-right {
  margin-right: 1%;
  padding: 8px;
  max-width: 1000px;
  background: #95EC69;
  position: relative;
  border-radius: 4px;
}
.chat-box-right:before {
  content: "";
  position: absolute;
  left: 100%;
  top: 50%;
  width: 0;
  height: 0;
  border-top: 9px solid transparent;
  border-left: 8px solid #95EC69;
  border-bottom: 9px solid transparent;
  transform: translateY(-50%);
}
.chat-name {
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  border-radius: 50%;
  background-color: #3C8AFF;
  color: #Ffffff;
}
.chat-msg-info {
  margin-top: 5px;
  margin-left: 10px;

  .info {
    color: rgba(0, 0, 0, 0.65);
    font-size: 16px;
    text-align: left;
    white-space: nowrap;
    overflow-wrap: break-word;
  }
}
.chat-system-head {
  width: 65px;
  height: 65px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  background-size: contain;
  background-image: url(../../../assets/icon/system.png);
  color: #Ffffff;
}
.chat-user-head {
  width: 65px;
  height: 65px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  background-size: contain;
  background-image: url(../../../assets/icon/avatar.png);
  color: #Ffffff;
}
.btn-voice {
  width: 35px;
  height: 35px;
  margin-top: 2px;
}
.chat-input {
  margin-top: 20px;
}
.text-item-right {
  justify-content: flex-end;
}
.text-item-right .chat-box {
  margin-left: 0;
  margin-right: 15px;
}
.text-item-right .chat-box:before {
  right: -8px;
  border-left: 8px solid #FFFFFF;
  border-right: none;
}
</style>
